﻿using System;
using System.Collections.Generic;
using System.Timers;
using com.youzu.warh.protocol;
using FlowCanvas;
using LogSystem;
using UnityEditor;
using UnityEngine;
using Yoozoo.Gameplay.City;
using Yoozoo.Gameplay.Liberty.AI;
using Yoozoo.Gta.Common;
using Yoozoo.Managers.ResourceManagerV2.Runtime;
using Yoozoo.Mars.Got;
using Random = UnityEngine.Random;

namespace Yoozoo.Gameplay.Liberty.StreetEvent
{
    [Serializable]
    public class StreetEventNpcConfig
    {
        public int npcId;
        public int initNum = 1;
    }
    
    [Serializable]
    public class StreetEventConfig
    {
        public int eventID;
        public float GravityUpdateDuration = 1f;
        public Transform pointRoot;

        [Header("NPC随机出生点父节点，用于蓝图AddMonsterGroup随机出生")]
        public Transform randomRoot;
        public Transform wallRoot;
        public Transform fenderRoot;
        public string pointShowerPath;
        [Header("该关卡用到的Npc类型，需要预加载")]
        public List<StreetEventNpcConfig> npcConfigList;

        [Header("该关卡用到的演绎动画，需要预加载")] 
        public List<string> npcAnimationList;

        private Dictionary<string, Transform> _pointMap;
        private Dictionary<string, AirWallDefiner> _wallMap;
      
        public void Init()
        {
            LocomotionAgent.GravityUpdateDuration = GravityUpdateDuration;
            
            if (pointRoot != null)
            {
                _pointMap = new Dictionary<string, Transform>(50);
                for (int i = 0; i < pointRoot.childCount; i++)
                {
                    Transform t = pointRoot.GetChild(i);
                    // if (t.childCount > 0)
                    // {
                    //     Debug.LogError(LogModule.LibertyScene,"蓝图点下不能包含子物体：" + t.name,t.gameObject);
                    //     return;
                    // }

#if UNITY_EDITOR
                    if (t.GetComponent<Renderer>())
                    {
                        Debug.LogError(LogModule.LibertyScene,"蓝图点下不能包含渲染组件：" + t.name,t.gameObject);
                        return;
                    }    
#endif
                    _pointMap[t.name] = t;
                }

                // 兼容老接口
                foreach (var tp in _pointMap)
                {
                    if (BlueprintUtils.BlueprintPoints.ContainsKey(tp.Key))
                    {
                        Debug.LogError(LogModule.LibertyScene,"蓝图点名称重复：" + tp.Key,tp.Value.gameObject);
                        return;
                    }
                    
                    BlueprintUtils.BlueprintPoints[tp.Key] = new BluePrintPoint()
                    {
                        position = tp.Value.position,
                        rotation = tp.Value.rotation,
                        eulerAngles = tp.Value.eulerAngles,
                        lossyScale = tp.Value.lossyScale,
                        forward = tp.Value.forward,
                    };
                }
            }

            if (wallRoot != null)
            {
                _wallMap = new Dictionary<string, AirWallDefiner>(50);
                var walls = wallRoot.GetComponentsInChildren<AirWallDefiner>(true);
                foreach (var wall in walls)
                {
                    if (_wallMap.ContainsKey(wall.gameObject.name))
                    {
                        Debug.LogError(LogModule.LibertyScene,"空气墙名称重复：" + wall.gameObject.name, wall.gameObject);
                        return;
                    }
                    _wallMap[wall.gameObject.name] = wall;
                }
            }

            if (randomRoot != null)
            {
                if (BlueprintUtils.RandomBlueprintPoints == null)
                {
                    BlueprintUtils.RandomBlueprintPoints = new List<BluePrintPoint>(randomRoot.childCount);
                }
                for (int i = 0; i < randomRoot.childCount; i++)
                {
                    var trans = randomRoot.GetChild(i);
                    BlueprintUtils.RandomBlueprintPoints.Add(new BluePrintPoint()
                    {
                        position = trans.position,
                        rotation = trans.rotation,
                        eulerAngles = trans.eulerAngles,
                        lossyScale = trans.lossyScale,
                        forward = trans.forward,
                    });
                }
            }
        }
        public void Dispose()
        {
            // 清除事件的蓝图点位信息
            if (_pointMap != null)
            {
                foreach (var tp in _pointMap)
                {
                    if (BlueprintUtils.BlueprintPoints.ContainsKey(tp.Key))
                    {
                        BlueprintUtils.BlueprintPoints.Remove(tp.Key);
                    }
                }
            }

            if (randomRoot!=null)
            {
                BlueprintUtils.RandomBlueprintPoints.Clear();
            }
        }

        public void UnlockAirWall(string wallName)
        {
            if (_wallMap.TryGetValue(wallName,out var wall))
            {
                wall.PlayUnlockEffect();
                Timers.inst.Add(2,1,(o =>
                {
                    if (wall && wall.gameObject)
                    {
                        wall.gameObject.SetActive(false);
                    }
                }));
            }
        }

        public void RevertAirWall(string wallName)
        {
            if (_wallMap.TryGetValue(wallName, out var wall))
            {
                wall.gameObject.SetActive(true);
            }
        }

        public void SwitchAllRacingFenders(bool enable)
        {
            fenderRoot.gameObject.SetActive(enable);
        }
        
        public void SwitchPointShower(bool active)
        {
#if UNITY_EDITOR
            if (string.IsNullOrEmpty(pointShowerPath))
            {
                return;
            }

            if (!active)
            {
                for (int i = 0; i < pointRoot.childCount; i++)
                {
                    Transform t = pointRoot.GetChild(i);
                    if (t.childCount > 0)
                    {
                        for (int j = t.childCount - 1; j >= 0; j--)
                        {
                            GameObject.DestroyImmediate(t.GetChild(j).gameObject);
                        }
                    }
                }
                return;
            }
            GameObject s = AssetDatabase.LoadAssetAtPath<GameObject>(pointShowerPath);
            for (int i = 0; i < pointRoot.childCount; i++)
            {
                Transform t = pointRoot.GetChild(i);
                var oo = GameObject.Instantiate(s, Vector3.zero, Quaternion.identity,t);
                oo.transform.localPosition = Vector3.zero;
                oo.transform.localRotation = Quaternion.identity;
            }
#endif
        }


#if UNITY_EDITOR
        public void OnDrawGizmos()
        {
            if (pointRoot)
            {
                for (int i = 0; i < pointRoot.childCount; i++)
                {
                    Transform t = pointRoot.GetChild(i);
                    Gizmos.color = Color.yellow;
                    Gizmos.DrawSphere(t.position,0.15f);
                }
            }
        }
#endif
    }
    
    public class StreetEventBase : MonoBehaviour
    {
        public StreetEventConfig eventConfig;

        public FlowScriptController blueprint;
        
        private ResLoader _npcResLoader;

        private bool isNpcCanReborn;

        [Header("开启NPC掉落物品")]
        public bool OpenNpcDeadDrop = false;

        [Header("开启NPC复活")] [HideInInspector]
        public bool OpenNpcRespawn;
        public float DaddyTime => baddyTime;
        public float RebornTime => rebornTime;
        
        [Header("开启主角复活")]
        public bool OpenPlayerRespawn = false;
        
        [Header("重生时间")] [SerializeField] [HideInInspector]
        private float rebornTime = 15;
        
        [HideInInspector][Header("无敌时间")] [SerializeField]
        private float baddyTime = 5;
        
        [Header("重生点位父节点")] [SerializeField]
        private Transform bornPoint;


        [Header("重生点是否随机，不随机会从NpcConfig中选配置的节点名称")] [SerializeField] [HideInInspector]
        private bool IsRandomReborn = true;

        [HideInInspector]
        public Transform[] BornPointList;
        
        [HideInInspector]
        public List<WaitRebornInfo> DeadNpcList;
        private List<WaitRebornInfo> waitRebornNpcList;
        private List<WaitRebornInfo> bornInvincibleNpcList;
        // 新成员变量，存储每个复活点的最后使用时间
        private Dictionary<Transform, float> lastUsedRebornPoints;
        private List<Transform> availableBornPoints;
        protected List<PropItem> AddedItemList;
        protected bool _dropItemConfigLoaded = false;
        public bool DropItemConfigLoaded => _dropItemConfigLoaded;
        
        // 任务相关
        [Header("任务数量统计给主角的Npc")] [SerializeField]
        private List<int> _taskHelperIds;
        private int _deadNpcCount = 0;
        private int _killNpcCount = 0;
        private int _hasTakeMoney = 0;
        
        protected virtual void Awake()
        {
            OnStart();
            LibertyConfigManager.GetInstance().LoadGameDropGroupConfig(() =>
            {
                _dropItemConfigLoaded = true;
            });
            if (OpenNpcRespawn || OpenPlayerRespawn)
            {
                DeadNpcList = new List<WaitRebornInfo>(16);
                waitRebornNpcList = new List<WaitRebornInfo>(16);
                bornInvincibleNpcList = new List<WaitRebornInfo>(16);
                lastUsedRebornPoints = new Dictionary<Transform, float>();
                availableBornPoints = new List<Transform>();
            }
        }
        
        protected virtual void OnStart()
        {
            if (bornPoint!=null)
            {
                var childCount = bornPoint.childCount;
                if (BornPointList!=null)
                {
                    BornPointList = new Transform[childCount];
                }

                if (BornPointList!=null)
                {
                    for (int i = 0; i < childCount; i++)
                    {
                        BornPointList[i] = bornPoint.GetChild(i);
                    }
                }
            }
        }
        public virtual void OnPreInit()
        {
            LibertyConst.OverrideAIPathGravityUpdateDuration = false;
            LibertyConfigManager.PLAYER_PROPERTY_NPCID = LibertyConst.DEFAULT_PLAYER_PROPERTY_NPCID;
            
            eventConfig?.Init();
            if (blueprint == null)
            {
                blueprint = GetComponentInChildren<FlowScriptController>(true);
            }
        }

        public virtual void OnLoad(Action<int> callback)
        {
            if (eventConfig != null)
            {
                if (_npcResLoader == null)
                {
                    _npcResLoader = ResLoader.Alloc();
                }

                bool npcLoadFinish = false;
                bool animationLoadFinish = false;
                
                var npcManager = LibertyManager.GetInstance("LibertyManager").NpcManager;
                
                // 加载npc
                for (int i = 0; i < eventConfig.npcConfigList.Count; i++)
                {
                    var cfg = eventConfig.npcConfigList[i];
                    PbAIPropertyDataConfig aiPropertyDataConfig = LibertyConfigManager.GetInstance().GetAIPropertyDataConfig(cfg.npcId);
                    if (aiPropertyDataConfig != null)
                    {
                        _npcResLoader.Add2Load(aiPropertyDataConfig.path, ((success, assetName, asset) =>
                        {
                            if (!success)
                            {
                                return;
                            }
                            
                            if (cfg.initNum <= 0)
                            {
                                cfg.initNum = 1;
                            }
                            npcManager.OnLoadNpc(aiPropertyDataConfig.id, aiPropertyDataConfig.type, aiPropertyDataConfig.name, asset as GameObject,cfg.initNum);
                        }));
                    }
                    
                }
                _npcResLoader.Load((() =>
                {
                    npcLoadFinish = true;

                    if (npcLoadFinish && animationLoadFinish)
                    {
                        callback?.Invoke(eventConfig.eventID);
                    }
                }));
                
                // 加载街区事件动画
                LibertyAnimationClipManager.GetInstance().PreloadStreetEventAnimationClips(eventConfig.npcAnimationList, () =>
                {
                    animationLoadFinish = true;

                    if (npcLoadFinish && animationLoadFinish)
                    {
                        callback?.Invoke(eventConfig.eventID);
                    }
                });
                
            }
        }

        public virtual void OnEnter()
        {   
            blueprint.StartBehaviour();
            
            BattleAgent.OnKill += OnKill;
            if (OpenNpcDeadDrop)
            {
                AddedItemList = new List<PropItem>();
                PropItem.OnPropItemTaken += OnPropItemTaken;
            }
        }

        public virtual void OnExit()
        {
            blueprint.StopBehaviour();
            eventConfig?.Dispose();
            
            BattleAgent.OnKill -= OnKill;
            if (OpenNpcDeadDrop)
            {
                PropItem.OnPropItemTaken -= OnPropItemTaken;
                if (AddedItemList!=null)
                {
                    for (int i = AddedItemList.Count - 1; i >=0; i--)
                    {
                        PropItem.DestroyPropItem(AddedItemList[i]);
                    }
                    AddedItemList.Clear();
                }
            }
        }

        private void OnPropItemTaken(int id, int entityId,long UID,PropItem propItem)
        {
            for (int i = AddedItemList.Count - 1; i >= 0; i--)
            {
                var item = AddedItemList[i];
                if (item.UID == UID)
                {
                    AddedItemList.RemoveAt(i);
                }
            }

            

            
            if (propItem.ItemConfig.type == 4) //4是美金道具
            {
                bool needUpdateTaskProgress = false;
                do
                {
                    // 玩家捡到钱
                    if (entityId == LibertyAIUtils.PLAYER_AI_ID)
                    {
                        needUpdateTaskProgress = true;
                        break;
                    }

                    // 是否属于帮手
                    if (_taskHelperIds != null)
                    {
                        var m = StreetEventManager.GetInstance("").GetMonsterByUniqueId(entityId);
                        if (m!=null && _taskHelperIds.Contains(m.streetNpcId))
                        {
                            needUpdateTaskProgress = true;
                            break;
                        }
                    }
                } while (false);
                
                if (needUpdateTaskProgress)
                {
                    //捡到钱事件抛出
                    _hasTakeMoney = _hasTakeMoney + propItem.ItemConfig.parameter_01;
                    
                    ResidentHandler.Inst.GetFunction("CityLuaFunction.OnGtaTaskProgressUpdate").Action(3,_hasTakeMoney);
                }
                
            }
        }

        /// <summary>
        /// 击杀回调
        /// </summary>
        /// <param name="uniqueId">被击杀的npc</param>
        /// <param name="killerUniqueId">击杀他的npc</param>
        /// <param name="weaponId">击杀用的武器</param>
        private void OnKill(int uniqueId,int killerUniqueId,int weaponId)
        {
            OnKillMonster(uniqueId,killerUniqueId,weaponId);
            if (OpenNpcDeadDrop)
            {
                OnNpcDropped(uniqueId);
            }

            if (OpenNpcRespawn || (OpenPlayerRespawn && uniqueId == LibertyAIUtils.PLAYER_AI_ID))
            {
                // 复活数据
                AIEntity aiEntity = LibertyAIUtils.GetNpc(uniqueId);
                if (uniqueId == LibertyAIUtils.PLAYER_AI_ID)
                {
                    DeadNpcList.Add(new WaitRebornInfo()
                    {
                        id = LibertyAIUtils.PLAYER_AI_ID,
                        startRebornTime = Time.time
                    });
                }
                else
                {
                    DeadNpcList.Add(new WaitRebornInfo()
                    {
                        id = uniqueId,
                        modelId = aiEntity.BirthData.modelResId,
                        startRebornTime = Time.time,
                        dropItemPackId =  aiEntity.BirthData.dropItemPackId,
                        rebornPoint = aiEntity.BirthData.rebornPoint
                    });
                }
            }
            else
            {
                if (uniqueId != LibertyAIUtils.PLAYER_AI_ID)
                {
                    _deadNpcCount = _deadNpcCount + 1;
                    if (_deadNpcCount == StreetEventManager.GetInstance().GetStreetMonsterCount())
                    {
                        //抛出击杀所有人目标事件
                        ResidentHandler.Inst.GetFunction("CityLuaFunction.OnGtaTaskProgressUpdate").Action(1,1);
                    }
                }
            }
            
            bool needUpdateTaskProgress = false;
            do
            {
                if (uniqueId == LibertyAIUtils.PLAYER_AI_ID)
                {
                    break;
                }
                    
                // 玩家击杀
                if (killerUniqueId == LibertyAIUtils.PLAYER_AI_ID)
                {
                    needUpdateTaskProgress = true;
                    break;
                }

                // 是否属于帮手
                if (_taskHelperIds!=null && killerUniqueId!=uniqueId)
                {
                    var m = StreetEventManager.GetInstance("").GetMonsterByUniqueId(killerUniqueId);
                    if (m!=null && _taskHelperIds.Contains(m.streetNpcId))
                    {
                        needUpdateTaskProgress = true;
                        break;
                    }
                }
            } while (false);

            if (needUpdateTaskProgress)
            {
                _killNpcCount = _killNpcCount + 1;
                ResidentHandler.Inst.GetFunction("CityLuaFunction.OnGtaTaskProgressUpdate").Action(2,_killNpcCount);
            }
        }

        protected virtual void OnKillMonster(int uniqueId,int killerUniqueId,int weaponId)
        {
            // 击杀回调
            StreetEventOnKillEvent.OnKill?.Invoke(uniqueId, killerUniqueId);

            if (uniqueId == LibertyAIUtils.PLAYER_AI_ID)
            {
                if (OpenPlayerRespawn)
                {
                    if (uniqueId == LibertyAIUtils.PLAYER_AI_ID)
                    {
                        ResidentHandler.Inst.GetFunction("CityLuaFunction.onStreetFightReborn").Action(StreetFightEvent.Instance.RebornTime);
                    }
                }
                else
                {
                    StreetEventManager.GetInstance().OnPlayerDead();
                }
            }
            else
            {
                StreetEventManager.GetInstance().OnKillMonster(uniqueId, killerUniqueId, weaponId);
            }
        }

        protected virtual void OnNpcDropped(int uniqueId)
        {
            var entity = LibertyAIUtils.GetNpc(uniqueId);
            if (entity != null)
            {
                var dropGroupsConfigs = LibertyConfigManager.GetInstance()
                    .GetGTA_game_dropgroupConfigs(entity.BirthData.dropItemPackId);
                var currentWeight = 0;
                var totalWeight = 0;
                if (dropGroupsConfigs != null)
                {
                    foreach (var drop in dropGroupsConfigs)
                    {
                        totalWeight += drop.weight;
                    }

                    var randomWeight = Random.Range(0, totalWeight);
                    foreach (var drop in dropGroupsConfigs)
                    {
                        currentWeight += drop.weight;
                        if (randomWeight <= currentWeight)
                        {
                            //生成道具
                            var item = PropItem.CreatePropItem(drop.item_id);
                            item.transform.position = entity.data.CurrentLerpPositin;
                            AddedItemList.Add(item);
                            break;
                        }
                    }
                }
            }
        }
        

        public virtual void OnPause()
        {
            Time.timeScale = 0f;
        }

        public virtual void OnResume()
        {
            Time.timeScale = 1f;
        }

        private void Update()
        {
            OnUpdate();
            if (OpenNpcRespawn || OpenPlayerRespawn)
            {
                NpcRespawnUpdate();
            }
        }

        private void NpcRespawnUpdate()
        {
            var deadNpcList = StreetFightEvent.Instance.DeadNpcList;
            if (deadNpcList != null && deadNpcList.Count > 0)
            {
                foreach (var deadNpcId in deadNpcList)
                {
                    waitRebornNpcList.Add(deadNpcId);
                }

                deadNpcList.Clear();
            }

            if (waitRebornNpcList.Count > 0)
            {
                for (int i = waitRebornNpcList.Count - 1; i >= 0; i--)
                {
                    var waitRebornInfo = waitRebornNpcList[i];
                    var info = waitRebornInfo;
                    if (Time.time - info.startRebornTime > StreetFightEvent.Instance.rebornTime)
                    {
                        Vector3 bornPosition = default;
                        Vector3 bornAngle = default;
                        Vector3 bornForward = default;
                        // 创建符合条件的复活点列表
                        if (IsRandomReborn) //随机复活点复活
                        {
                            availableBornPoints.Clear();
                            foreach (var bornTrans in StreetFightEvent.Instance.BornPointList)
                            {
                                if (!lastUsedRebornPoints.ContainsKey(bornTrans) ||
                                    Time.time - lastUsedRebornPoints[bornTrans] > 3f)
                                {
                                    availableBornPoints.Add(bornTrans);
                                }
                            }

                            // 从列表中随机选择一个复活点
                            if (availableBornPoints.Count > 0)
                            {
                                int bornPointListIndex = UnityEngine.Random.Range(0, availableBornPoints.Count);
                                var selectedBornTrans = availableBornPoints[bornPointListIndex];
                                bornPosition = selectedBornTrans.position;
                                bornAngle = selectedBornTrans.eulerAngles;
                                bornForward = selectedBornTrans.forward;
                                lastUsedRebornPoints[selectedBornTrans] = Time.time;
                            }
                        }
                        else
                        {
                            var point = BlueprintUtils.GetBlueprintPoint(waitRebornInfo.rebornPoint);
                            bornPosition = point.position;
                            bornAngle = point.eulerAngles;
                            bornForward = point.forward;
                        }

                        // 确保找到了可用的复活点
                        if (bornPosition != default)
                        {
                            if (info.id == LibertyAIUtils.PLAYER_AI_ID)
                            {
                                LibertyAIUtils.PlayerController.RebornPlayer();
                                LibertyAIUtils.PlayerController.PlayerTransmission(
                                    bornPosition,
                                    bornAngle,
                                    true, true);
                                LibertyAIUtils.PlayerController.playerEntity.AIEntity.data.invincible = true;
                                LibertyAIUtils.PlayerController.playerEntity.AIEntity.battleAgent.StartFlashing();
                            }
                            else
                            {
                                AIBirthData birthData = new AIBirthData();
                                birthData.uniqueId = info.id;
                                birthData.position = bornPosition;
                                birthData.forward = bornForward;
                                birthData.modelResId = info.modelId;
                                birthData.animState = "";
                                birthData.sideType = SideType.Madness;
                                birthData.isBoss = false;
                                birthData.isStreetEvent = true;
                                birthData.isStatic = false;
                                birthData.dropItemPackId = info.dropItemPackId;
                                LibertyAIUtils.AIManager.AddNpc(birthData, 1003);
                                //设置无敌
                                var npc = LibertyAIUtils.AIManager.NpcBirthManager.GetNpc(info.id);
                                if (npc != null)
                                {
                                    npc.data.invincible = true;
                                    //无敌特效
                                    npc.battleAgent.StartFlashing();
                                }
                            }

                            waitRebornInfo.reBornTime = Time.time;
                            bornInvincibleNpcList.Add(waitRebornInfo);
                            //复活
                            waitRebornNpcList.RemoveAt(i);
                        }
                    }
                }
            }

            if (bornInvincibleNpcList.Count > 0)
            {
                for (int i = bornInvincibleNpcList.Count - 1; i >= 0; i--)
                {
                    var bornInfo = bornInvincibleNpcList[i];
                    if (Time.time - bornInfo.reBornTime > StreetFightEvent.Instance.baddyTime)
                    {
                        if (bornInfo.id == LibertyAIUtils.PLAYER_AI_ID)
                        {
                            LibertyAIUtils.PlayerController.playerEntity.AIEntity.data.invincible = false;
                        }
                        else
                        {
                            var npc = LibertyAIUtils.AIManager.NpcBirthManager.GetNpc(bornInfo.id);
                            if (npc != null)
                            {
                                npc.data.invincible = false;
                            }
                        }

                        bornInvincibleNpcList.RemoveAt(i);
                    }
                }
            }
        }

        protected virtual void OnUpdate()
        {
            
        }

#if UNITY_EDITOR
        private void OnDrawGizmos()
        {
            eventConfig?.OnDrawGizmos();
        }
#endif
        
    }
}